// if iostream sync off #define USE_IOSTREAM
#include <cmath>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <vector>
#include <string>
#include <memory>
#include <utility>
#include <iostream>
#include <type_traits>
// sorcery begin
#include <cstdint>
#include <typeindex>
#include <stdexcept>
#include <functional>
#include <unordered_map>

namespace scd
{
    using std::cin, std::cout, std::string, std::vector, std::unique_ptr;
    using std::declval, std::getchar, std::putchar, std::move, std::forward, std::swap, std::endl, std::make_unique;
    using std::is_floating_point, std::is_integral, std::is_reference, std::is_same, std::true_type, std::false_type, std::decay_t, std::enable_if_t, std::size_t;

    template <typename...>
    using void_t = void;

    template <typename T>
    using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;

    template <typename, typename = void>
    struct has_read : false_type
    {
    };

    template <typename T>
    struct has_read<T, void_t<decltype(declval<T &>().read())>> : true_type
    {
    };

    template <typename T>
    inline constexpr bool has_read_v = has_read<T>::value;

    template <typename, typename = void>
    struct has_print : false_type
    {
    };

    template <typename T>
    struct has_print<T, void_t<decltype(declval<T>().print())>> : true_type
    {
    };

    template <typename T>
    inline constexpr bool has_print_v = has_print<T>::value;

    template <typename, typename = void>
    struct is_callable : false_type
    {
    };

    template <typename T>
    struct is_callable<T, void_t<decltype(declval<T>()())>> : true_type
    {
    };

    template <typename T>
    inline constexpr bool is_callable_v = is_callable<T>::value;

    template <typename Raw = int, typename T = decay_t<Raw>>
    inline auto read() -> enable_if_t<is_integral<T>::value, T>
    {
        T x = 0;
#ifdef USE_IOSTREAM
        cin >> x;
#else
        bool fl = false;
        char c = getchar();
        while (c < '0' || c > '9')
            fl |= (c == '-'), c = getchar();
        while (c >= '0' && c <= '9')
        {
            x = (x << 3) + (x << 1) + (c ^ 48);
            c = getchar();
        }
        return fl ? -x : x;
#endif
    }

    template <typename Raw, typename T = decay_t<Raw>>
    inline auto read() -> enable_if_t<!is_integral<T>::value, T>
    {
        T x;
        cin >> x;
        return x;
    }

    template <typename Raw, typename T = decay_t<Raw>>
    inline auto read(Raw &&x) -> enable_if_t<is_integral<T>::value>
    {
#ifdef USE_IOSTREAM
        cin >> x;
#else
        x = 0;
        bool fl = false;
        char c = getchar();
        while (c < '0' || c > '9')
            fl |= (c == '-'), c = getchar();
        while (c >= '0' && c <= '9')
        {
            x = (x << 3) + (x << 1) + (c ^ 48);
            c = getchar();
        }
#endif
    }

    inline void read(char *p)
    {
#ifdef USE_IOSTREAM
        cin >> p;
#else
        char c = getchar();
        while (isspace(c))
            c = getchar();
        while (c != EOF && !isspace(c))
        {
            *p++ = c;
            c = getchar();
        }
        *p = '\0';
#endif
    }

    template <typename T>
    inline auto read(T &&x) -> enable_if_t<has_read_v<T>>
    {
        x.read();
    }

    template <typename T>
    inline auto read(T &&x) -> enable_if_t<!is_integral<decay_t<T>>::value &&
                                           !has_read_v<T>>
    {
        cin >> x;
    }

    template <typename... T>
    inline void read(T &&...x)
    {
        (read(forward<T>(x)), ...);
    }

    template <typename Raw = int, typename T = decay_t<Raw>>
    inline auto print(Raw x) -> enable_if_t<is_integral<T>::value>
    {
#ifdef USE_IOSTREAM
        cout << x;
#else
        if (x < 0)
        {
            putchar('-');
            x = -x;
        }
        if (x > 9)
            print(x / 10);
        putchar(x % 10 + '0');
#endif
    }

    template <int d = 6, typename Raw = double, typename T = decay_t<Raw>>
    inline auto print(Raw x) -> enable_if_t<is_floating_point<T>::value>
    {
#ifdef USE_IOSTREAM
        // TODO
        cout << std::fixed << std::precision(d) << x;
#else
        printf("%.*f", d, x);
#endif
    }

    inline void print(char x)
    {
#ifdef USE_IOSTREAM
        cout.put(x);
#else
        putchar(x);
#endif
    }

    inline void print(const char *x)
    {
        while (*x)
#ifdef USE_IOSTREAM
            cout.put(*x++);
#else
            putchar(*x++);
#endif
    }

    template <typename T>
    inline auto print(T &&x) -> enable_if_t<has_print_v<T>>
    {
        x.print();
    }

    template <typename Raw, typename T = decay_t<Raw>>
    inline auto print(Raw &&x)
        -> enable_if_t<!is_integral<T>::value &&
                       !is_floating_point<T>::value &&
                       !has_print<Raw>::value>
    {
        cout << x;
    }

    template <typename... T>
    inline void print(T &&...x)
    {
        (print(forward<T>(x)), ...);
    }

    template <typename... T>
    inline void printws(T &&...x)
    {
        (print(forward<T>(x), ' '), ...);
    }

    template <typename... T>
    inline void println(T &&...x)
    {
        printws(x...);
        print('\n');
    }

    template <typename T = int>
    class Vec : public vector<T>
    {
    public:
        using vector<T>::vector;

        void read() noexcept
        {
            for (auto &item : *this)
                scd::read(item);
        }

        void print() const noexcept
        {
            for (const auto &item : *this)
                scd::print(item);
        }
    };

    class Str : public string
    {
    public:
        using string::string;

        Str(const string &s) noexcept : string(s) {}

        Str(string &&s) noexcept : string(move(s)) {}

        Str(const char *s) noexcept : string(s) {}

        void read() noexcept { cin >> *this; }

        void print() const noexcept { scd::print(c_str()); }
    };

    // todo! IDIOM copy and swap
    class CowStr
    {
    private:
        Str *s;
        unsigned *cnt;

        void release() noexcept
        {
            if (--*cnt == 0)
            {
                delete s;
                delete cnt;
            }
        }

    public:
        CowStr() noexcept : s(new Str()), cnt(new unsigned(1)) {}

        CowStr(const CowStr &c) noexcept : s(c.s), cnt(c.cnt) { ++*cnt; }

        CowStr(CowStr &&c) noexcept : s(c.s), cnt(c.cnt)
        {
            c.s = nullptr;
            c.cnt = nullptr;
        }

        explicit CowStr(const Str &str) noexcept : s(new Str(str)), cnt(new unsigned(1)) {}
        explicit CowStr(Str &&str) noexcept : s(new Str(move(str))), cnt(new unsigned(1)) {}
        explicit CowStr(const string &str) noexcept : s(new Str(str)), cnt(new unsigned(1)) {}
        explicit CowStr(string &&str) noexcept : s(new Str(move(str))), cnt(new unsigned(1)) {}
        explicit CowStr(const char *str) noexcept : s(new Str(str)), cnt(new unsigned(1)) {}

        CowStr &operator=(CowStr other) noexcept
        {
            swap(*this, other);
            return *this;
        }

        friend void swap(CowStr &a, CowStr &b) noexcept
        {
            swap(a.s, b.s);
            swap(a.cnt, b.cnt);
        }

        ~CowStr() noexcept
        {
            if (cnt)
                release();
        }

        auto &operator[](int i) noexcept { return (*s)[i]; }
        void read() noexcept { s->read(); }
        void print() const noexcept { s->print(); }
    };

    namespace sorcery
    {
        using namespace std;

        template <bool errout = false, typename F, typename = enable_if_t<is_callable_v<F>>>
        void guard(F &&f)
        {
            try
            {
                f();
            }
            catch (exception &e)
            {
                if constexpr (errout)
                    cerr << e.what() << endl;
            }
            catch (...)
            {
                if constexpr (errout)
                    cerr << "Unknown exception occurred at line " << __LINE__ << endl;
            }
        }

        template <size_t idx = 0, size_t N = 1,
                  typename T, typename Ret, typename... Args,
                  typename = enable_if_t<is_polymorphic<T>::value>>
        void change_fun(T *c, Ret (*f)(Args...))
        {
            auto p = reinterpret_cast<void ***>(c);
            auto new_vp = new void *[N];
            memcpy(new_vp, *p, sizeof(void *) * N);
            new_vp[idx] = reinterpret_cast<void *>(f);
            *p = new_vp;
        }

        using i64 = int64_t;

        struct GrcBase
        {
            virtual i64 call(i64, i64, i64) = 0;
            virtual i64 f0(i64, i64, i64) = 0;
            virtual i64 f1(i64, i64, i64) = 0;
        };

        struct Grc : GrcBase
        {
            i64 call(i64 = 0, i64 = 0, i64 = 0) override { return 0; }
            i64 f0(i64 = 0, i64 = 0, i64 = 0) override { return 0; }
            i64 f1(i64 = 0, i64 = 0, i64 = 0) override { return 0; }
        };

        template <typename Ret, typename... Args>
        auto make_grc(Ret (*f)(Args...))
        {
            auto g = new Grc{};
            change_fun<0, 3>(g, f);
            return g;
        }

        auto call_grc(Vec<tuple<Grc *, i64, i64, i64>> v, i64 (Grc::*f)(i64, i64, i64) = &Grc::call)
        {
            Vec<i64> res;
            for (const auto &[g, a, b, c] : v)
                res.push_back((g->*f)(a, b, c));
            return res;
        }

        struct ExceptYes
        {
        };

        struct ExceptNo
        {
        };

#ifdef FUCK_IF
#define if(cond)                                           \
    try                                                    \
    {                                                      \
        (cond) ? (throw ExceptYes()) : (throw ExceptNo()); \
    }                                                      \
    catch (ExceptYes)
#define else catch (ExceptNo)
#endif
    }

    namespace exports
    {
        using scd::print, scd::println, scd::printws, scd::read;
        using scd::Vec, scd::Str, scd::CowStr;
    }
}

using namespace scd::exports;

namespace test
{
    using namespace std;
    using namespace scd::sorcery;

    inline void main()
    {
        auto g0 = make_grc(+[](Grc *self, int64_t a, int64_t b, int64_t c)
                           {
                               println(a + b + c);
                           });
        auto g1 = make_grc(+[](Grc *self, int64_t a, int64_t b, int64_t c)
                           {
                               println(a * b * c);
                           });
        call_grc({{g0, 1, 2, 3}, {g1, 5, 6, 7}});
    }
}
#include <bits/stdc++.h>
using namespace std;
int main(int argc, const char **argv)
{
#ifdef _DEBUG
    freopen("//?/I:\\desktop\\down\\data\\destory/destory1.in", "r", stdin);
#else
    freopen("destory.in", "r", stdin);
    freopen("destory.out", "w", stdout);
#endif
    int n = read(), m = read(), q = read();
    Vec<Vec<>> g(n + 1);
    while (m--)
    {
        int u = read(), v = read();
        g[u].push_back(v);
        g[v].push_back(u);
    }
    Vec<> vis(n + 1);
    decltype(g) dis(n + 1, Vec<>(n + 1));
    constexpr auto inf = 0x3f3f3f3f;
    auto dij = [&](int s)
    {
        fill(begin(dis[s]), end(dis[s]), inf);
        fill(begin(vis), end(vis), 0);
        auto &d = dis[s];
        d[s] = 0;
        queue<int> q;
        q.push(s);
        while (!q.empty())
        {
            int u = q.front();
            q.pop();
            if (vis[u])
                continue;
            for (int v : g[u])
                if (d[v] > d[u] + 1)
                {
                    d[v] = d[u] + 1;
                    q.push(u);
                }
        }
    };
    Vec<Vec<>> can(n + 1);
    for (int i = 1; i <= n; ++i)
    {
        dij(i);
        for (int j = 1; j <= n; ++j)
            if (dis[i][j] != inf)
                can[i].push_back(j);
    }
    while (q--)
    {
        int L = read(), R = read();
        int res = inf;
        for (int l = L; l <= R; ++l)
            for (int r = l; r <= R; ++r)
                if (r - l + 1 < res)
                {
                    bool fl = 1;
                    for (int i = L; i < l; ++i)
                        if (auto it = lower_bound(begin(can[i]), end(can[i]), l);
                            it == end(can[i]) || *it > r)
                        {
                            fl = 0;
                            break;
                        }
                    if (fl)
                    {
                        for (int i = r + 1; i <= R; ++i)
                            if (auto it = lower_bound(begin(can[i]), end(can[i]), l);
                                it == end(can[i]) || *it > r)
                            {
                                fl = 0;
                                break;
                            }
                    }
                    if (fl)
                        res = min(res, r - l + 1);
                }
        if (res == inf)
            res = -1;
        println(res);
    }
    return 0;
}
